package com.cdg.transaction.service.impl;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionSynchronizationAdapter;
import org.springframework.transaction.support.TransactionSynchronizationManager;

import com.cdg.transaction.service.TransactionalService;

public class TransactionalServiceImpl implements TransactionalService {

	private Logger logger = LoggerFactory.getLogger(TransactionalServiceImpl.class);

	@Override
	@Transactional(propagation = Propagation.REQUIRES_NEW)
	public void executeWithNewTransactional(Execute execute) {
		execute.doExecute();
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRES_NEW)
	public <T> T executeWithNewTransactional(ExecuteWithReturn<T> execute) {
		return execute.doExecute();
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public void executeWithTransactional(Execute execute) {
		execute.doExecute();
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public <T> T executeWithTransactional(ExecuteWithReturn<T> execute) {
		return execute.doExecute();
	}

	@Override
	public void executeAfterCommit(final Execute execute) {
		if (!TransactionSynchronizationManager.isSynchronizationActive()) {
			logger.debug("Execute immediately without active Synchronization");
			execute.doExecute();
			return;
		}
		logger.debug("Register to transactionSynchronizationManager");
		TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {

			@Override
			public void afterCommit() {
				logger.debug("Execute after commit");
				execute.doExecute();
			}
		});
	}

	@Override
	public void executeBeforeCommit(final Execute execute) {
		if (!TransactionSynchronizationManager.isSynchronizationActive()) {
			logger.debug("Execute immediately without active Synchronization");
			execute.doExecute();
			return;
		}
		logger.debug("Register to transactionSynchronizationManager");
		TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
			@Override
			public void beforeCommit(boolean readOnly) {
				logger.debug("Execute before commit");
				execute.doExecute();
			}
		});
	}
}
